package start.demo01.datatype.json.interfaces;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.serializer.SerializerFeature;
import org.apache.commons.lang3.StringUtils;
import start.demo01.datatype.json.json.JSONPath;
import start.demo01.datatype.json.pool.CacheMap;

import java.util.ArrayList;
import java.util.List;

import static start.demo01.datatype.json.constant.Constant.*;
import static start.demo01.datatype.json.json.JSONPath.branch;


//JSON操作
public abstract class JSONEditor {

    protected String name;//编辑器名称
    protected String args;
    protected CacheMap map;


    public void setMap(CacheMap map) {
        this.map = map;
    }

    public JSONEditor(String args) {
        this.args = args;
    }

    /**
     * 等jsonpath回调吧
     *
     * @param node 下一节点信息
     * @param obj  操作元素
     */
    public void apply(JSONPath.Node node, Object obj) {
        System.out.println("执行函数:" + name + "(" + args + ")");
        switch (node.getType()) {
            case NODE_TYPE1_1://.key对象入口
                JSONObject object = (JSONObject) obj;
                print("被执行元素->\n", object);
                if (StringUtils.isEmpty(args))//操作当前元素
                    operationObject(object, node.getKey());
                else {//操作当前元素的字段
                    JSONObject jsonObject;
                    if (node.getKey() == null)
                        operation(object);
                    else {
                        jsonObject = object.getJSONObject(node.getKey());
                        operation(jsonObject);
                    }
                }
                break;
            case NODE_TYPE2_1://[1]索引入口
                JSONArray jsonArray = (JSONArray) obj;
                print("被执行元素->\n", jsonArray);
                if (StringUtils.isEmpty(args)) {//无参 执行元素
                    if (node.getKey().equals(F)) {
                        int i = jsonArray.size();
                        while (i > 0) {
                            operationArray(jsonArray, --i);
                        }
                    } else {
                        for (int i : indexs(node.getKey())) {
                            operationArray(jsonArray, i);
                        }
                    }
                } else {//有参 执行对象属性
                    JSONArray array = branch(node.getKey(), jsonArray);
                    for (Object o : array) {
                        operation((JSONObject) o);
                    }
                }
                break;
        }
    }

    //无参
    protected abstract void operationObject(JSONObject object, String key);

    //无参
    protected abstract void operationArray(JSONArray array, int index);

    /**
     * 有参对象操作
     *
     * @param object 操作对象
     */
    protected abstract void operation(JSONObject object);

    //索引排序
    protected Integer[] indexs(String arr) {
        String[] split = arr.split(",");
        Integer[] ins = new Integer[split.length];
        for (int i = 0; i < split.length; i++) {
            ins[i] = Integer.parseInt(split[i]);
        }
        //插排 降序
        for (int i = 1; i < ins.length; i++) {
            int currentElement = ins[i];
            int j;
            for (j = i - 1; j >= 0 && currentElement > ins[j]; j--)
                ins[j + 1] = ins[j];
            ins[j + 1] = currentElement;
        }
        return ins;
    }

    //对象参数处理{x,y,z},{x},{xc,cd}
    protected List<String[]> deal() {
        List<String[]> list = new ArrayList<>();
        int i = 0;
        while ((i = args.indexOf('{', i)) != -1) {
            int end = args.indexOf('}', i);
            String params = args.substring(i + 1, end);
            i = end;
            list.add(params.split(","));
        }
        return list;
    }

    public static void print(String head, Object object) {
        System.out.println(head + JSON.toJSONString(object,
                SerializerFeature.PrettyFormat,
                SerializerFeature.WriteMapNullValue,
                SerializerFeature.WriteDateUseDateFormat,
                SerializerFeature.WriteNullListAsEmpty));
    }
}
